package org.batatasframework.values;

import java.util.Collections;
import java.util.Date;
import java.util.List;

public class ObjectValueGetter implements ValueGetter{
	
	public static ObjectValueGetter valueOf(Object sourceValue){
		if(sourceValue instanceof String){
			return new ObjectValueGetter(StringValueGetter.valueOf((String)sourceValue));
		}
		
		if(sourceValue instanceof byte[]){
			return new ObjectValueGetter(BytesValueGetter.valueOf((byte[])sourceValue));
		}
		
		return new ObjectValueGetter(sourceValue);
	}
	
	protected final Object sourceValue;

	@Override
	public boolean is(Object target) {
		return target.equals(sourceValue);
	}

	private ObjectValueGetter(Object sourceValue){
		this.sourceValue = sourceValue;
	}

	@Override
	public String getString() {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).getString();
		}
		return sourceValue.toString();
	}

	@Override
	public Integer getInteger() {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).getInteger();
		}
		if(sourceValue instanceof Number){
			return ((Number) sourceValue).intValue();
		}
		return null;
	}

	@Override
	public Long getLong() {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).getLong();
		}
		if(sourceValue instanceof Number){
			return ((Number) sourceValue).longValue();
		}
		return null;
	}

	@Override
	public Boolean getBoolean() {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).getBoolean();
		}
		if(sourceValue instanceof Boolean){
			return (Boolean) sourceValue;
		}else if(sourceValue instanceof Number){
			return ((Number) sourceValue).intValue() == 1;
		}
		return null;
	}

	@Override
	public Double getDouble() {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).getDouble();
		}
		if(sourceValue instanceof Number){
			return ((Number) sourceValue).doubleValue();
		}
		return null;
	}

	@Override
	public <T> T getObject(Class<T> clazz) {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).getObject(clazz);
		}
		return clazz.cast(sourceValue);
	}

	@Override
	public Date getDate(Object arg) {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).getDate(arg);
		}
		
		if(sourceValue instanceof Date){
			return (Date)sourceValue;
		}
		
		if(sourceValue instanceof Number){
			return new Date(((Number) sourceValue).longValue());
		}
		
		return null;
	}

	@Override
	public Class<?> getClassType() {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).getClassType();
		}
		return sourceValue.getClass();
	}

	@Override
	public <E extends Enum<E>> E toEnum(Class<E> clazz) {
		if(sourceValue instanceof ValueGetter){
			return ((ValueGetter) sourceValue).toEnum(clazz);
		}
		return clazz.cast(sourceValue);
	}

	@Override
	@SuppressWarnings("unchecked")
	public <T> List<T> asList() {
		return Collections.singletonList((T)sourceValue);
	}

}
